import { createSelector, createStructuredSelector } from 'reselect';
import bbox from 'turf-bbox';
import lineString from 'turf-linestring';

export const COUNTRIES_COORDINATES = {
  VA: [12.453386544971766, 41.903282179960115],
  SM: [12.441770157800141, 43.936095834768004],
  LI: [9.516669472907267, 47.13372377429357],
  SZ: [31.133334512056365, -26.316650778409212],
  LU: [6.130002806227083, 49.611660379121076],
  FM: [158.1499743237623, 6.916643696007725],
  MH: [171.38000017574655, 7.103004311216239],
  TV: [179.21664709402887, -8.516651999041073],
  PW: [134.62654846699218, 7.487396172977981],
  EH: [-9.652522218250112, 26.119166685993378],
  MC: [7.406913173465057, 43.73964568785249],
  KI: [173.01757082854942, 1.338187505624603],
  KM: [43.240244098693324, -11.70415769566847],
  AD: [1.5164859605055199, 42.5000014435459],
  TT: [-61.51703088544974, 10.651997089577264],
  RW: [30.058585919064114, -1.9516442100632503],
  SS: [31.580025592787308, 4.829975198277964],
  NL: [4.914694317400972, 52.35191454666443],
  SI: [14.51496903347413, 46.0552883087945],
  SK: [17.11698075223461, 48.15001832996171],
  QA: [51.532967894299304, 25.286556008906587],
  ME: [19.266306924118226, 42.465972512881706],
  LK: [79.85775060925641, 6.931965758182116],
  PH: [120.9802713035424, 14.606104813440538],
  TZ: [39.26639597769457, -6.798066736124383],
  CH: [6.140028034091699, 46.21000754707626],
  MA: [-7.618313291698712, 33.60192207425848],
  DM: [-61.387012981803366, 15.301015644283325],
  DJ: [43.148001667052256, 11.595014464255485],
  MY: [101.69803741674644, 3.168611730712371],
  JP: [139.74946157054467, 35.686962764371174],
  GM: [-16.591701489212596, 13.45387646031594],
  MK: [21.4334614651425, 42.00000612290586],
  BB: [-59.61652673505159, 13.10200258275114],
  BJ: [2.518044740568598, 6.401954422782467],
  BI: [29.360006061528395, -3.376087220374643],
  VC: [-61.212062420279324, 13.14827882786841],
  LC: [-61.00000818036955, 14.00197348933034],
  KN: [-62.71700931969934, 17.302030455489387],
  MU: [57.49999385460973, -20.166638571353246],
  GD: [-61.74164322607476, 12.052633401720414],
  BH: [50.58305171591019, 26.236136290485945],
  AG: [-61.85003381513866, 17.118036518314113],
  UY: [-56.17299814703597, -34.856095707590725],
  TG: [1.22081126074562, 6.133882930268385],
  TN: [10.179678099212026, 36.80277813623144],
  AE: [55.27802846473787, 25.231942012376066],
  TM: [58.38329911177465, 37.949994933110986],
  ZM: [28.28138173611427, -15.414698409335926],
  ZW: [31.042763572062825, -17.815843835777798],
  TL: [125.57945593170507, -8.559388408546454],
  VU: [168.31664058356864, -17.733350404025828],
  HN: [-87.2194751979415, 14.103990759076396],
  GY: [-58.167028647480606, 6.8019736927520285],
  IS: [-21.950014487179544, 64.15002361973922],
  HT: [-72.33798044690553, 18.54297045473237],
  UG: [32.581377667121046, 0.318604813383331],
  SR: [-55.16703088542437, 5.835030129922586],
  NE: [2.114710186530374, 13.51865181050647],
  TJ: [68.77387935270173, 38.56003521631658],
  PY: [-57.643451027901335, -25.294457117057675],
  NI: [-86.27043751890119, 12.154962438756115],
  SL: [-13.236161599012746, 8.471957271098177],
  PK: [73.16468862105955, 33.70194180895959],
  NP: [85.31469635222788, 27.718637772477223],
  ZA: [18.43304229922603, -33.91806510862875],
  PG: [147.19250362059358, -9.464707825867777],
  SB: [159.94976573360566, -9.437994295089595],
  PA: [-79.53498301041077, 8.969963049094872],
  MD: [28.85771113965143, 47.005023619670624],
  MZ: [32.58721710397009, -25.953331628778983],
  SO: [45.36473175245874, 2.068627192947531],
  OM: [58.593312132608844, 23.613324807728134],
  MN: [106.91466990374653, 47.91861925856074],
  NA: [17.08354610054181, -22.570006084383806],
  NG: [3.3895852125984334, 6.445207512093191],
  GW: [-15.598360841320755, 11.865023822980561],
  JO: [35.93135406687412, 31.951971105827454],
  LT: [25.3166352932829, 54.68336631175862],
  LV: [24.099965371403187, 56.95002382316096],
  KG: [74.58325836390367, 42.875025305090105],
  LS: [27.483273069984477, -29.316674378681626],
  MG: [47.51467804152986, -18.914691492032148],
  EC: [-78.5019969671124, -0.2130423220355624],
  CR: [-84.08599721127536, 9.936958288356607],
  SV: [-89.2049870794599, 13.711947505494038],
  JM: [-76.7674337136691, 17.977076623830897],
  TD: [15.047202455462298, 12.115042394810644],
  GQ: [8.783277545821136, 3.750015278026183],
  ER: [38.933323525759306, 15.333339252681924],
  HR: [15.999994668245677, 45.80000673327254],
  EE: [24.72804072947855, 59.43387737948592],
  MW: [33.78330195998353, -13.983295065469179],
  GT: [-90.52891143656154, 14.623080521448173],
  GA: [9.457965045823698, 0.3853886097185182],
  FJ: [178.44170731537986, -18.133015931371233],
  CL: [-70.66898671317483, -33.448067956934096],
  MR: [-15.975340414890013, 18.086427021247516],
  ML: [-8.001984963249697, 12.65196052632325],
  LB: [35.507762351377664, 33.8739209756269],
  GE: [44.788849590997984, 41.72695584707759],
  KZ: [71.427774209483, 51.18112530425759],
  LA: [102.59998002015476, 17.96669272762739],
  CG: [15.282743633848668, -4.257239913197509],
  GN: [-13.682180886123945, 9.53346870502179],
  CI: [-4.041994118507091, 5.321942826098564],
  CA: [-79.42196665298843, 43.70192573640844],
  RS: [20.466044822020535, 44.82059130444674],
  BN: [114.93328405666227, 4.883331114619239],
  BO: [-68.15193104910219, -16.49602775504337],
  BZ: [-88.76707299981655, 17.252033507246892],
  CF: [18.558288125287277, 4.366644306349087],
  CM: [11.514704896854425, 3.868646520754112],
  AL: [19.81888301461521, 41.327540709491586],
  AM: [44.51160553175208, 40.18309659414189],
  AZ: [49.860271303257775, 40.39721789134302],
  KH: [104.91468862118643, 11.55197598855841],
  BG: [23.314708152110086, 42.68529528393054],
  BY: [27.56468129665825, 53.901923295043105],
  BT: [89.63901403703, 27.472985859175765],
  BW: [25.91194779328538, -24.646313457438907],
  AU: [151.1832339501475, -33.91806510862875],
  BF: [-1.5266696149164432, 12.372261836543373],
  BA: [18.383001666953305, 43.850022398954934],
  MM: [96.16473175266185, 16.785299963188777],
  TO: [-175.22056447761656, -21.13851235669864],
  SC: [55.44998978559113, -4.6166316539734],
  ST: [6.733325153234773, 0.3334021188329075],
  WS: [-171.73864160860316, -13.841545042448445],
  MT: [14.514710651312782, 35.89973248193087],
  MV: [73.499947467955, 4.1667081898118],
  IL: [34.76806589955174, 32.08193733304165],
  CV: [-23.51668888497221, 14.916698017328656],
  BS: [-77.35004378427612, 25.08339011535122],
  CY: [33.36663488641415, 35.166676451654496],
  NZ: [174.76302698707957, -36.848054894932005],
  VN: [105.8480683412422, 21.035273107737055],
  TR: [29.008055727002613, 41.10694201243979],
  HU: [19.081374818759684, 47.50195218499135],
  YE: [44.20464752393843, 15.356679154263645],
  RO: [26.0980007953504, 44.43531766349457],
  SY: [36.29805003041707, 33.50197985420613],
  PT: [-9.14681216410213, 38.72466873648784],
  SD: [32.532233380011576, 15.590024084277673],
  NO: [10.748033347372314, 59.91863614500187],
  PL: [20.998053692465305, 52.25194648839556],
  KP: [125.75274485499392, 39.02138455800434],
  IE: [-6.250851540391068, 53.335006994584944],
  LR: [-10.799660436775923, 6.314581647160139],
  CU: [-82.3661280299533, 23.1339046995422],
  CZ: [14.464033917048539, 50.08528287347832],
  KW: [47.97635528762527, 29.371663488629565],
  DO: [-69.90203094331503, 18.472018713195382],
  GH: [-0.21866159896069348, 5.551980464445933],
  LY: [13.180011758078194, 32.89250001935369],
  FI: [24.93218048284558, 60.17750923256807],
  DK: [12.561539888703294, 55.68051004902594],
  BR: [-46.62696583905523, -23.55673372837896],
  BE: [4.33137074969045, 50.83526293533032],
  BD: [90.40663360810754, 23.725005570312817],
  AO: [13.23248118266855, -8.836340255012658],
  DZ: [3.048606670909237, 36.765010656628135],
  US: [-73.98196278740681, 40.75192492259464],
  VE: [-66.91898305105042, 10.502944413033333],
  UA: [30.514682110472165, 50.43531318760722],
  UZ: [69.29298696088779, 41.31364774160721],
  ES: [-3.6852975446125242, 40.40197212311381],
  SE: [18.095388874180912, 59.35270581286585],
  TH: [100.51469879369489, 13.751945064087977],
  PE: [-77.05200795343472, -12.04606681752557],
  SN: [-17.47507598705056, 14.717777583623274],
  KR: [126.99778513820195, 37.56829495838895],
  MX: [-99.1329340602939, 19.444388301415472],
  DE: [13.399602764700546, 52.523764522251156],
  CN: [121.43455881982015, 31.218398311228327],
  CD: [15.313026023171744, -4.327778243275986],
  IN: [88.32272979950551, 22.49691515689642],
  GR: [23.731375225679358, 37.98527209055226],
  IQ: [44.391922914564134, 33.34059435615865],
  ET: [38.69805857534868, 9.035256221295754],
  IR: [51.42239817500899, 35.673888627001304],
  AR: [-58.399477232331435, -34.600555749907414],
  AF: [69.18131419070505, 34.51863614490031],
  AT: [16.364693096743736, 48.20196113681686],
  TW: [121.568333333333, 25.0358333333333],
  GB: [-0.11866770247593195, 51.5019405883275],
  SA: [46.770795798688255, 24.642779007816443],
  RU: [37.6135769672714, 55.75410998124818],
  IT: [12.481312562873995, 41.89790148509894],
  KE: [36.81471100047145, -1.2814008832377795],
  ID: [106.82749176247012, -6.172471846798885],
  CO: [-74.08528981377441, 4.598369421147822],
  EG: [31.248022361126118, 30.051906205103705],
  FR: [2.33138946713035, 48.86863878981461],
  SG: [103.85387481909902, 1.2949793251059418],
  HK: [114.18306345846304, 22.30692675357551],
};

const getSelectedContext = (state, { context }) => context;
const getTopNodes = (state, { topNodes }) => topNodes && topNodes.targetNodes;

export const getOriginGeoId = createSelector(
  getSelectedContext,
  (selectedContext) => (selectedContext ? selectedContext.worldMap.geoId : null)
);

export const getOriginCoordinates = createSelector(
  getOriginGeoId,
  (originGeoId) => (originGeoId ? COUNTRIES_COORDINATES[originGeoId] : null)
);

export const getWorldMapFlows = createSelector(
  [getOriginGeoId, getOriginCoordinates, getTopNodes],
  (originGeoId, originCoordinates, countries) => {
    if (!originGeoId || !originCoordinates || !countries) {
      return [];
    }

    const contextFlows = countries
      ? countries
          .filter((country) => country.geoId !== originGeoId)
          .sort((a, b) => {
            if (a.value < b.value) return -1;
            if (a.value > b.value) return 1;
            return 0;
          })
          .map((country, index) => ({
            ...country,
            strokeWidth: index + 1,
            coordinates: COUNTRIES_COORDINATES[country.geo_id],
            geoId: country.geo_id,
          }))
      : [];

    const contextFlowsWithCoordinates = contextFlows.filter(
      (f) => typeof f.coordinates !== 'undefined'
    );

    if (contextFlowsWithCoordinates.length !== contextFlows.length) {
      // eslint-disable-next-line no-console
      console.warn('World map flows are missing geoids. Check your database.');
    }

    const [minX, , maxX] = bbox(
      lineString(contextFlowsWithCoordinates.map((f) => f.coordinates))
    );
    const medianX = (maxX + minX) / 2;
    const originLeftOfBbox = originCoordinates[0] < medianX;
    const pointOfControl = {
      x: originLeftOfBbox ? minX - 10 : maxX + 10,
    };

    const getCurveStyle = (destination) => {
      if (destination[0] < pointOfControl.x) {
        // left
        return 'forceDown';
      }
      // right
      return 'forceUp';
    };

    return contextFlowsWithCoordinates.map((destination) => ({
      ...destination,
      curveStyle: getCurveStyle(destination.coordinates),
    }));
  }
);

export const getWorldMapProps = createStructuredSelector({
  flows: getWorldMapFlows,
  originGeoId: getOriginGeoId,
  selectedContext: getSelectedContext,
  originCoordinates: getOriginCoordinates,
});
